import { _decorator, Component, Label, Tween, tween } from 'cc';
const { ccclass, property } = _decorator;

type Callback = () => void;

@ccclass('NumericAutoIncrement')
export class NumericAutoIncrement extends Component {
    private currentValue: number = 0;
    public get CurrentValue(): number { return this.currentValue; }

    private targetValue: number = 0;
    public get TargetValue(): number { return this.targetValue; }

    private duration: number = 1;
    public get Duration(): number { return this.duration; }

    private frequency: number = 0.05;
    public get Frequency(): number { return this.frequency; }
    
    private tweenInst: Tween<any> | null = null;
    private finishCallback: Callback | null = null;
    private label: Label = null;

    onLoad() {
        this.label = this.getComponent(Label);
    }

    /**
     * 启动自增动画
     * @param current 当前值
     * @param target 目标值
     * @param duration 总时长（秒）
     * @param frequency 递增频率（秒）
     * @param onFinish 完成回调
     */
    public async startIncrement(current: number, target: number, duration: number, frequency: number, onFinish?: Callback): Promise<void> {
        if (!this.label) return;
        // 如果有正在进行的 tween，先停止并设置为上一次目标值
        if (this.tweenInst) {
            this.tweenInst.stop();
            this.label.string = this.targetValue.toString();
        }
        this.currentValue = current;
        this.targetValue = target;
        this.duration = duration;
        this.frequency = frequency;
        this.finishCallback = onFinish || null;
        this.label.string = current.toString();

        const stepCount = Math.ceil(duration / frequency);
        const stepValue = (target - current) / stepCount;
        let cur = current;
        let count = 0;

        return new Promise<void>((resolve) => {
            this.tweenInst = tween({})
                .call(() => {
                    this.label.string = cur.toFixed(0); // 保留两位小数
                })
                .repeat(stepCount, tween({})
                    .delay(frequency)
                    .call(() => {
                        count++;
                        cur += stepValue;
                        if (count >= stepCount) {
                            cur = target;
                        }
                        this.label.string = cur.toFixed(0); // 保留两位小数
                    })
                )
                .call(() => {
                    this.label.string = target.toString();
                    this.tweenInst = null;
                    if (this.finishCallback) this.finishCallback();
                    resolve();
                })
                .start();
        });
    }

    /**
     * 同步完成动画并回调 ( 立即完成 )
     */
    public finishImmediately(isFinishCallback: boolean = true): void {
        if (this.tweenInst) {
            this.tweenInst.stop();
            this.tweenInst = null;
            if (this.label) this.label.string = this.targetValue.toString();
            if (isFinishCallback && this.finishCallback) this.finishCallback();
        }
    }
}
